#ifndef __PVMINSTREAMHELPERS_H__
#define __PVMINSTREAMHELPERS_H__

#include "pvm/pvmhelperapi.h"
#include "pvm/pvmdefs.h"
#include "lib/pvmsystem.h"

#include "lib/memory/pvmmemory.h"

class PVMHRefMemObject : public PVMAllocableObject
{
public:
	PVMHRefMemObject(pvm_int8* data, pvm_size size, pvm_bool ownMemory, TFreeMemmoryProc memFreeProc);
	~PVMHRefMemObject();

	pvm_int AddRef();
	pvm_int Release();

	PVM_FORCEINLINE pvm_size Size() {return dataSize;};
	PVM_FORCEINLINE pvm_int8* Data() {return data;};
protected:
	pvm_int refCount;
	pvm_size dataSize;
	pvm_int8* data;
	pvm_bool ownMemory;
	TFreeMemmoryProc memFreeProc;
};

class PVMHMemmoryInputStream : public IPvmInStream, public PVMAllocableObject
{
	PVMHMemmoryInputStream();
public:
	static IPvmInStream* Create(pvm_int8* dataPtr, pvm_size dataSize, pvm_bool ownMemory, TFreeMemmoryProc memFreeProc);

	virtual ~PVMHMemmoryInputStream();

	virtual pvm_size Read(void *buf, pvm_size size);
	virtual pvm_bool Seek(pvm_file_size pos, TPvmSeek origin);
	virtual pvm_file_size Tell();
	virtual void Close();
	virtual pvm_file_size Size();
	virtual IPvmInStream* OpenCopy();
	virtual pvm_bool Seekable();
	virtual pvm_bool Eof();
protected:
	PVMHRefMemObject* memObj;
	pvm_file_size position;
};

class PVMHFileInputStream : public IPvmInStream, public PVMAllocableObject
{
	PVMHFileInputStream();
public:
	static IPvmInStream* CreateW(const pvm_char* fileName);

	virtual ~PVMHFileInputStream();

	virtual pvm_size Read(void *buf, pvm_size size);
	virtual pvm_bool Seek(pvm_file_size pos, TPvmSeek origin);
	virtual pvm_file_size Tell();
	virtual void Close();
	virtual pvm_file_size Size();
	virtual IPvmInStream* OpenCopy();
	virtual pvm_bool Seekable();
	virtual pvm_bool Eof();
protected:
	pvm_char* name;
	PVMFileHandle file;
	pvm_bool eof;
};

class PVMInCallbacksStream : public IPvmInStream, public PVMAllocableObject
{
public:
	PVMInCallbacksStream(IPVMReadCallbacks* callbacks, void *src);
	virtual ~PVMInCallbacksStream();

	virtual pvm_size Read(void *buf, pvm_size size);
	virtual pvm_bool Seek(pvm_file_size pos, TPvmSeek origin);
	virtual pvm_file_size Tell();
	virtual void Close();
	virtual pvm_file_size Size();
	virtual IPvmInStream* OpenCopy();
	virtual pvm_bool Seekable();
	virtual pvm_bool Eof();
protected:
	IPVMReadCallbacks* callbacks;
	void *src;
};

#endif
